let _Vue;

class Vuex {
    constructor(options) {
        let {state, actions, mutations, getters} = options;
        this.state = {};
        this.actions = {};
        this.mutations = {};
        this.getters = {};

        this.state = new _Vue({
            data() {
                return state;
            }
        });

        Object.keys(actions).forEach(name => {
            this.actions[name] = (params) => {
                this.actions[name](this, params);
            }
        });

        Object.keys(mutations).forEach(name => {
            this.mutations[name] = (params) => {
                this.mutations[name](this.state, params);
            }
        });

        Object.keys(getters).forEach(name => {
            Object.defineProperty(this.getters, name, {
                get: () => {
                    return this.getters[name](this.state);
                }
            })
        });
    }

    dispatch(name, params) {
        this.actions[name](params);
    }

    commit(name, params) {
        this.mutations[name](params);
    }

    static install(Vue) {
        _Vue = Vue;
        _Vue.mixin({
            beforeCreate() {
                if (this.$options.store) {
                    this.$store = this.$options.store;
                } else {
                    this.$store = this.$parent && this.$parent.$store;
                }
            }
        });
    }
}
